/**
 * 自定义Proxy代理类
 */

import {
  getDataType,
  updateWatcher,
  deepAttributeInObject
} from './utils/index.js'

class LveProxy {
  constructor(instance, key) {
    this.instance = instance
    this.key = key
  }
  init(key) {
    const data = this.instance
    let obj = this.key
    let arrayType = null // 当前数组的操作类型
    obj = getDataType(obj) === 'null' ? {} : obj // Proxy不能传入不是对象的类型，所以在这里转一下
    return new Proxy(obj, {
      get(target, property, receiver) {
        if (getDataType(target) === 'array' && property !== 'length') {
          arrayType = property // 在get中获取操作类型，set中触发
        }
        return target[property]
      },
      set(target, property, value, receiver) {
        if (!Reflect.set(target, property, value, receiver)) {
          return false
        }
        if (getDataType(target) === 'array') { // 数组类型值改变 会触发两次，第一次将值修改，第二次将length属性改变
          // 在下面 get 方法中触发
          if (property !== 'length' && arrayMethods.includes(arrayType) && arrayType) {
            updateWatcher(data.$watchers[key], value, arrayType)
          }
        } else { // 对象类型值改变
          updateWatcher(data.$watchers[key][property], value) // 数据改变 watcher触发修改对应界面上的值
          const watchKey = Object.keys(data.$watch).find(item => {
            if (item.indexOf(key) !== -1 && (item.indexOf(property) !== -1 || deepAttributeInObject(target, property))) {
              return item
            }
          }) // 主动触发watch对象的方法
          if (watchKey) {
            data.$watch[watchKey].call(data, value)
          }
        }
        return true
      }
    })
  }
}

export default LveProxy